﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using DropBoxAuthSimple;
using SharpDropBoxClient;

namespace Silverlight_Simple_Test_App
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }

        DropBoxApp dbApp;

        private void goButton_Click(object sender, RoutedEventArgs e)
        {
            // Settings moved to settings.cs file (tired of accidently publishing my password, and having to go change it immediately)
            var appKey = Settings.AppKey;
            var appSecret = Settings.AppSecret;
            var testEMail = String.IsNullOrEmpty(EmailBox.Text) ? Settings.TestEMail : EmailBox.Text;
            var testAccountPwd = String.IsNullOrEmpty(PasswordBox.Password) ? Settings.TestAccountPwd : PasswordBox.Password;

            dbApp = new DropBoxApp(appKey, appSecret);
            dbApp.MimicDropBoxFileSystemLocally = true;
            //CreateAnAccount();

            NormalAuthSession(testEMail, testAccountPwd);
        }

        private void CreateAnAccount()
        {
            // Not working at the moment
            dbApp.CreateAccount(Settings.TestAccountCreateEMail, Settings.TestAccountPwd, "test", "account", (result, ex) =>
            {
                this.result.Items.Add(String.Format("Created an account :{0}", ex == null));
                var text = ex;
            });
        }

        private void NormalAuthSession(string testEMail, string testAccountPwd)
        {
            if (!dbApp.NeedAuthInfo)
            {
                getRootMetaData();
            }
            else
            {
                dbApp.LoginAndGetAuthCredentials(testEMail, testAccountPwd, (success, ex) =>
                {
                    result.Items.Add(String.Format("Logged in and get credentials :{0}", ex == null));
                    if (success)
                    {
                        getRootMetaData();
                    }
                });
            }
        }

        private void getRootMetaData()
        {
            // Need to write MetaData Routines..

            dbApp.ListDirAndContents("", new List<string>(), (obj) =>
            {
                result.Items.Add(String.Format("listed root contents :{0}", obj.Error == null));
                if (obj.Error != null)
                {
                    var test = obj.Error;
                }
                else
                {
                    var data = new StringBuilder();

                    TraverseJSonAndOutputToStringBuilder(obj.Dictionary, data);
                    //uploadFile();
                    Dispatcher.BeginInvoke(() =>
                    {
                        fileList.Visibility = System.Windows.Visibility.Visible;
                        result.Visibility = System.Windows.Visibility.Collapsed;
                        fileList.ItemsSource = obj.Dictionary;
                        dbApp.GetFileEntry("", (new[] { "list=true" }).ToList(), (objResult) =>
                        {
                            getFile();
                        });
                    });
                }
            });
        }

        private void getFile()
        {
            dbApp.GetFile(@"\Photos\Sample Album\Boston City Flow.jpg", (fName, ex) =>
            {
                if (ex != null)
                {
                    result.Items.Add(String.Format("got Sample pic :{0}", ex == null));
                    var test = ex;
                }
                else
                {
                    var x = fName;
                }
            });

            dbApp.GetFileURI("rotate.png", (uri, ex) =>
            {
                if (ex != null)
                {
                    result.Items.Add(String.Format("got rotate.png URI :{0}", ex == null));
                    var ex1 = ex;
                }
            });
            dbApp.GetFile("rotate.png", (fName, ex) =>
            {
                result.Items.Add(String.Format("got totate.png :{0}", ex == null));
                if (ex != null)
                {
                    var test = ex;
                }
                else
                {
                    var x = fName;
                }
                uploadFile();
            });
        }

        private void uploadFile()
        {
            System.IO.MemoryStream ms = null;
            System.IO.MemoryStream fileStream = null;
            System.IO.StreamWriter sw = null;
            try
            {
                using (ms = new System.IO.MemoryStream())
                using (sw = new System.IO.StreamWriter(ms))
                {
                    sw.WriteLine("this is a test.");
                    sw.Flush();
                    ms.Position = 0;
                    fileStream = new System.IO.MemoryStream(ms.GetBuffer());
                }
                dbApp.UploadFile("Photos", "test.txt", fileStream, (ex) =>
                {
                    result.Items.Add(String.Format("uploaded text.txt :{0}", ex == null));
                    var x = ex;
                    cleanupUpload();
                    moveFile();
                });
            }
            catch (Exception ex)
            {
                if (fileStream != null)
                {
                    fileStream.Dispose();
                }
                fileStream = null;
            }
        }

        private void moveFile()
        {
            dbApp.MovePathOrFile(@"Getting Started.pdf", @"Photos\deleteme.pdf", (result) =>
            {
                this.result.Items.Add(String.Format("moved Gettign Started.pdf :{0}", result.Error == null));
                var text = result.Error;
                copyFile();
            });
        }

        private void copyFile()
        {
            dbApp.CopyPathOrFile(@"Photos\deleteme.pdf", @"Getting Started.pdf", (result) =>
            {
                this.result.Items.Add(String.Format("copied deleteme.pdf :{0}", result.Error == null));
                var text = result.Error;
                deleteFile();
            });
        }

        private void cleanupUpload()
        {
            dbApp.DeletePathOrFile(@"Photos\test.txt", (ex) =>
            {
                result.Items.Add(String.Format("CreateAnAccount test.tx :{0}", ex == null));
                var text = ex;
                createDir();
            });
        }

        private void deleteFile()
        {
            dbApp.DeletePathOrFile(@"Photos\deleteme.pdf", (ex) =>
            {
                result.Items.Add(String.Format("CreateAnAccount delteme.pdf :{0}", ex == null));
                var text = ex;
                createDir();
            });
        }

        private void createDir()
        {
            dbApp.CreateDirectory(@"Test Directory", (result) =>
            {
                this.result.Items.Add(String.Format("CreateAnAccount Test Dir :{0}", result.Error == null));
                var text = result.Error;
                deleteDir();
            });
        }

        private void deleteDir()
        {
            dbApp.DeletePathOrFile(@"Test Directory", (ex) =>
            {
                result.Items.Add(String.Format("Delete Test Dir :{0}", ex == null));
                var text = ex;
                getThumbnail();
            });
        }

        private void getThumbnail()
        {
            dbApp.GetThumbbnail(@"rotate.png", (strm, ex) =>
            {
                result.Items.Add(String.Format("Got Thumbnail :{0}", ex == null));
                var text = ex;
                if (strm != null)
                    strm.Dispose();

                //Complete!
            });
        }

        private void OutputAccountInfo()
        {
            dbApp.GetAccountInfo((dict, ex) =>
            {
                if (ex != null)
                {
                    var test = ex;
                }
                else
                {
                    var sb = new StringBuilder();
                    TraverseJSonAndOutputToStringBuilder(dict, sb);
                    var str = sb.ToString();
                    Dispatcher.BeginInvoke(() =>
                    {
                        fileList.Visibility = System.Windows.Visibility.Collapsed;
                        result.Visibility = System.Windows.Visibility.Visible;

                        //result.Text = str;
                        result.Items.Add(str);
                    });
                }
            });
        }

        private static void TraverseJSonAndOutputToStringBuilder(IDictionary<string, object> dict, StringBuilder sb)
        {
            foreach (var item in dict)
            {
                var val = item.Value.ToString();
                if (!String.IsNullOrEmpty(val) && val != item.Value.GetType().FullName)
                {
                    sb.Append(item.Key + "=" + val + ", ");
                }
                else
                {
                    IDictionary<string, object> dict2 = item.Value as IDictionary<string, object>;
                    if (dict2 != null)
                    {
                        sb.Append(item.Key + ": {");
                        TraverseJSonAndOutputToStringBuilder(dict2, sb);
                        sb.Append("}, ");
                    }
                }
            }
        }
    }
}